using System.Net;
using CampusModel;
using CampusModel.Enum;
using CampusModel.Model;
using Microsoft.EntityFrameworkCore;
using PublicProject.PublicClass.ExtensionException;

namespace CampusDataOperationLibrary;

public class TeacherCourseOperation(CampusModelDbContext context)
{

    public async Task<bool> AddCourseAsync(string userId, string courseName, string className)
    {
        var user = await GetUserByIdAsync(userId);
        var teacher = await GetTeacherAsync(user);
        var myClass = await GetClassByNameAsync(className);
        var course = new Course(courseName, teacher.Id, myClass.Id);
        context.Courses.Add(course);
        return await context.SaveChangesAsync() > 0;
    }
    private async Task<Class> GetClassByNameAsync(string className)
    {
        var myClass = await context.Classes.FirstOrDefaultAsync(c => c.ClassName == className) ?? throw new ExceptionWithStatus(HttpStatusCode.NotFound, "班级不存在");
        return myClass;
    }
    private async Task<User> GetUserByIdAsync(string id)
    {
        var userId = int.Parse(id);
        var user = await context.Users.FindAsync(userId) ?? throw new ExceptionWithStatus(HttpStatusCode.NotFound, "用户不存在");
        return user;
    }

    public async Task<List<Course>> GetCoursesByTeacherIdAsync(string id)
    {
        var user = await GetUserByIdAsync(id);
        var userId = (await GetTeacherAsync(user)).Id;
        var courses = await context.Courses.Include(x => x.Class).Include((x => x.Class.Students)).Where(c => c.TeacherID == userId).ToListAsync();
        return courses;
    }


    private async Task<Teacher> GetTeacherAsync(User user)
    {
        var teacher = await context.Teachers.FindAsync(user.UserId) ?? throw new ExceptionWithStatus(HttpStatusCode.NotFound, "教师不存在");
        return teacher;
    }
    public async Task<int> AddAttendanceRecordAsync(string id, string inputCourseName, int inputLayerId)
    {
        var user = await GetUserByIdAsync(id);
        var teacher = await GetTeacherAsync(user);
        var courseId = (await context.Courses.FirstOrDefaultAsync(c => c.CourseName == inputCourseName && c.TeacherID == teacher.Id))?.CourseID ?? throw new ExceptionWithStatus(HttpStatusCode.NotFound, "课程不存在");
        var atteendanceRecord = new AttendanceRecord(inputLayerId, courseId);
        context.AttendanceRecords.Add(atteendanceRecord);
        await context.SaveChangesAsync();
        return atteendanceRecord.AttendanceID;
    }
    public async Task<(List<Course>, List<List<AttendanceRecord>>)> GetAttendanceStatisticalListAsync(string id)
    {
        var user = await GetUserByIdAsync(id);
        var teacher = await GetTeacherAsync(user);
        var courses = await context.Courses.Where(c => c.TeacherID == teacher.Id).ToListAsync();
        var attendanceRecords = new List<List<AttendanceRecord>>();
        foreach (var course in courses)
        {
            attendanceRecords.Add(await context.AttendanceRecords.Include((x => x.Course)).Where(a => a.CourseID == course.CourseID).ToListAsync());
        }
        return (courses, attendanceRecords);
    }
    public async ValueTask<(int attendedCount, int absentCount, List<Student>)> GetCourseAttendanceDateAsync(int attendanceId)
    {
        var attendanceRecord = await context.AttendanceRecords.Include((x => x.Course)).Include((x => x.Course.Class)).Include((x => x.Course.Class.Students)).Include(attendanceRecord => attendanceRecord.Students).FirstOrDefaultAsync(a => a.AttendanceID == attendanceId) ?? throw new ExceptionWithStatus(HttpStatusCode.NotFound, "考勤记录不存在");
        var attendedCount = attendanceRecord.Students.Count;
        var absentStudents = attendanceRecord.Course.Class.Students.Where(s => attendanceRecord.Students.All(a => a.Id != s.Id)).ToList();
        var absentCount = attendanceRecord.Course.Class.Students.Count - attendedCount;
        return (attendedCount, absentCount, absentStudents);
    }
    public async ValueTask<bool> DeleteCourseAsync(string id, string courseName)
    {
        var user = await GetUserByIdAsync(id);
        var teacher = await GetTeacherAsync(user);
        var course = await context.Courses.Include(x => x.AttendanceRecords).FirstOrDefaultAsync(c => c.CourseName == courseName && c.TeacherID == teacher.Id) ?? throw new ExceptionWithStatus(HttpStatusCode.NotFound, "课程不存在");
        if (course.AttendanceRecords.Count > 0)
        {
            context.AttendanceRecords.RemoveRange(course.AttendanceRecords);
            await context.SaveChangesAsync();
        }
        context.Courses.Remove(course);
        return await context.SaveChangesAsync() > 0;
    }
}